package com.dreamoo.common.threadpool.factory;

import com.dreamoo.common.exception.BusinessException;
import com.dreamoo.common.result.ResultCode;
import com.dreamoo.common.threadpool.CompletableFutureExecutor;
import com.dreamoo.common.threadpool.DreamooThreadPoolConstant;
import com.dreamoo.common.threadpool.DreamooThreadPoolExecutor;
import lombok.Data;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.*;

/**
 * @author 山顶洞人郑某
 * @className ThreadPoolExecutorFactory.java 线程池工厂
 * @date 2025 05 06
 */
@Data
public class DreamooThreadPoolExecutorFactory {

    /**
     * 线程池集合
     */
    private static final Map<String, DreamooThreadPoolExecutor> threadPoolMap = new ConcurrentHashMap<>();

    private static final Map<String ,CompletableFutureExecutor> comFuturePool = new ConcurrentHashMap<>();
    /**
     * 初始化线程池集合
     */
    public DreamooThreadPoolExecutorFactory() {
        //自定义线程池
        threadPoolMap.put(DreamooThreadPoolConstant.DREAM_PROCESSOR_POOL,createDreamProcessorPool());
        threadPoolMap.put(DreamooThreadPoolConstant.SLEEP_DATA_ANALYSIS_POOL,createSleepDataAnalysisPool());
        threadPoolMap.put(DreamooThreadPoolConstant.USER_NOTIFICATION_POOL,createUserNotificationPool());
        threadPoolMap.put(DreamooThreadPoolConstant.BACKGROUND_TASK_POOL,createBackgroundTaskPool());

        //用于支持CompletableFutureExecutor 传递的线程池
        comFuturePool.put(DreamooThreadPoolConstant.DREAM_PROCESSOR_POOL,createComDreamProcessorPool());
    }



    public  void addThreadPoolExecture(String name,DreamooThreadPoolExecutor executor) {
        threadPoolMap.put(name,executor);
    }

    public CompletableFutureExecutor getCompletableExecutor(String name) {
        CompletableFutureExecutor completableFutureExecutor = comFuturePool.get(name);
        if (completableFutureExecutor == null ) {
            throw new NullPointerException("线程池未找到");
        }
        return completableFutureExecutor;
    }
    /**
     * 获取线程池
     * @param name 线程池名称
     * @return 线程池
     */
    public  DreamooThreadPoolExecutor getThreadPoolExecutor(String name) {
        DreamooThreadPoolExecutor dreamooThreadPoolExecutor = threadPoolMap.get(name);
        if (dreamooThreadPoolExecutor == null) {
            throw new BusinessException(ResultCode.THREAD_POOL_NOT_FOUND);
        }
        return dreamooThreadPoolExecutor;
    }
    /**
     * 创建梦境处理线程池
     * @return DreamooThreadPoolExecutor
     */
    public  DreamooThreadPoolExecutor createDreamProcessorPool() {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                Runtime.getRuntime().availableProcessors() + 1,
                Runtime.getRuntime().availableProcessors() * 2,
                60L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(1000),
                DreamooThreadPoolNameFactory.Builder.dreamProcessorThreadFactory(),
                new ThreadPoolExecutor.CallerRunsPolicy()
        );
        return new DreamooThreadPoolExecutor(executor);
    }
    
    /**
     * 创建睡眠数据分析线程池
     * @return DreamooThreadPoolExecutor
     */
    public  DreamooThreadPoolExecutor createSleepDataAnalysisPool() {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                2,
                5,
                120L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(200),
                DreamooThreadPoolNameFactory.Builder.sleepDataAnalysisThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );
        return new DreamooThreadPoolExecutor(executor);
    }

    public CompletableFutureExecutor createComDreamProcessorPool() {
        return new CompletableFutureExecutor(
                Runtime.getRuntime().availableProcessors() + 1,
                Runtime.getRuntime().availableProcessors() * 2,
                60L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(1000),
                DreamooThreadPoolNameFactory.Builder.dreamProcessorThreadFactory(),
                new ThreadPoolExecutor.CallerRunsPolicy()
        );
    }
    
    /**
     * 创建用户通知线程池
     * @return DreamooThreadPoolExecutor
     */
    public  DreamooThreadPoolExecutor createUserNotificationPool() {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                3,
                10,
                60L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(500),
                DreamooThreadPoolNameFactory.Builder.userNotificationThreadFactory(),
                new ThreadPoolExecutor.DiscardOldestPolicy()
        );
        return new DreamooThreadPoolExecutor(executor);
    }
    
    /**
     * 创建后台任务线程池
     * @return DreamooThreadPoolExecutor
     */
    public DreamooThreadPoolExecutor createBackgroundTaskPool() {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                2,
                4,
                300L,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(100),
                DreamooThreadPoolNameFactory.Builder.backgroundTaskThreadFactory(),
                new ThreadPoolExecutor.DiscardPolicy()
        );
        return new DreamooThreadPoolExecutor(executor);
    }
    
    /**
     * 创建自定义线程池
     * @param corePoolSize 核心线程数
     * @param maximumPoolSize 最大线程数
     * @param keepAliveTime 空闲线程存活时间
     * @param timeUnit 时间单位
     * @param queueCapacity 队列容量
     * @param namePrefix 线程名前缀
     * @param rejectedPolicy 拒绝策略
     * @return DreamooThreadPoolExecutor
     */
    public  DreamooThreadPoolExecutor createCustomPool(
            int corePoolSize,
            int maximumPoolSize,
            long keepAliveTime,
            TimeUnit timeUnit,
            int queueCapacity,
            String namePrefix,
            RejectedExecutionHandler rejectedPolicy
    ) {
        ThreadPoolExecutor executor = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                timeUnit,
                new LinkedBlockingQueue<>(queueCapacity),
                DreamooThreadPoolNameFactory.Builder.customThreadFactory(namePrefix),
                rejectedPolicy
        );
        return new DreamooThreadPoolExecutor(executor);
    }
} 